home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / C / Frameworks / TransSkel 3.24 / Demos / C Demos / ManyWind / ManyWind.c next >
Text File  |  1995-03-21  |  9KB  |  367 lines

  1. /*
  2.  * Bug: doesn't properly keep bottom of window from going off screen.
  3.  *
  4.  * ManyWind -- TransSkel demonstration
  5.  *
  6.  * This application allows up to twenty windows to be created at once,
  7.  * with the New item under the File menu.  The name of each window
  8.  * appears under the Window menu (which is not created until at least
  9.  * one window exists).  Selecting the window name from the Window menu
  10.  * brings the window to the front.  For every window created, Skel is
  11.  * told to create a new handler.  If the window's close box is clicked,
  12.  * the handler removes the window name from the Window menu, disposes
  13.  * of the window, and removes itself from the window handler list.  If
  14.  * the window was the last window, the Window menu handler removes
  15.  * itself from the menu handler list.
  16.  *
  17.  * When the first window is created, a Color menu also appears.  This
  18.  * allows the color of the content region of the frontmost window to
  19.  * be changed.  It goes away when the last window is closed.
  20.  *
  21.  * To quit, select Quit from the File menu or type command-Q.
  22.  *
  23.  * ManyWind demonstrates dynamic window and menu creation and disposal.
  24.  * It also shows how handler procedures may be shared among handlers
  25.  * for different windows.
  26.  *
  27.  * 21 Apr 88 Version 1.00
  28.  * - Created.  Paul DuBois.
  29.  * 29 Jan 89 Version 1.01
  30.  * - Conversion for TransSkel 2.0.
  31.  * 30 Jan 91 Version 1.02
  32.  * - Conversion for TransSkel 3.00.
  33.  * 05 Jun 93 Version 1.03
  34.  * - Conversion for THINK C 6.0.
  35.  * 13 Nov 93
  36.  * - Added Close item to file menu.
  37.  * 11 Feb 94
  38.  * - Minor revisions and bug fixes.
  39.  * 15 Feb 94
  40.  * - Added item checking for Color and Window menus.
  41.  * 21 Feb 94
  42.  * - Updated for TransSkel 3.11.
  43.  * 21 Mar 95
  44.  * - Updated for TransSkel 3.19.
  45.  */
  46.  
  47. # include    "TransSkel.h"
  48.  
  49. # define    maxWind    20    /* maximum number of windows existing at once */
  50.  
  51.  
  52. enum                /* menu numbers */
  53. {
  54.     aMenuNum = skelAppleMenuID,    /* Apple menu */
  55.     fMenuNum,                    /* File menu */
  56.     wMenuNum,                    /* Window menu */
  57.     cMenuNum                    /* Color menu */
  58. };
  59.  
  60.  
  61. enum                /* File menu item numbers */
  62. {
  63.     newWind = 1,
  64.     closeWind,
  65.     /* --- */
  66.     quitApp = 4
  67. };
  68.  
  69. enum                /* Color menu items numbers */
  70. {
  71.     cWhite = 1,
  72.     cLtGray,
  73.     cGray,
  74.     cDkGray,
  75.     cBlack
  76. };
  77.  
  78.  
  79. static void MakeWindow(void);
  80.  
  81.  
  82. MenuHandle    fileMenu;
  83. MenuHandle    windowMenu;
  84. MenuHandle    colorMenu;
  85.  
  86. short    windCount = 0;    /* number of currently existing windows */
  87. long    windNum = 0;    /* id of last window created */
  88.  
  89.  
  90. /* ------------- */
  91. /* Menu handling */
  92. /* ------------- */
  93.  
  94.  
  95. static pascal void
  96. DoFileMenu (short item)
  97. {
  98. WindowPtr    w;
  99.  
  100.     switch (item)
  101.     {
  102.         case newWind:                    /* make a new window */
  103.             MakeWindow ();
  104.             break;
  105.         case closeWind:
  106.             SkelClose (FrontWindow ());
  107.             break;
  108.         case quitApp:                    /* tell SkelEventLoop() to quit */
  109.             SkelStopEventLoop ();
  110.             break;
  111.     }
  112. }
  113.  
  114.  
  115. static pascal void
  116. DoWindowMenu (short item)
  117. {
  118. Str255        iTitle, wTitle;
  119. WindowPtr    w;
  120.  
  121.     GetMenuItemText (windowMenu, item, iTitle);    /* get window name */
  122.     for (w = FrontWindow (); w != nil; w = (WindowPtr) ((WindowPeek)w)->nextWindow)
  123.     {
  124.         GetWTitle (w, wTitle);
  125.         if (EqualString (iTitle, wTitle, false, true))
  126.         {
  127.             SelectWindow (w);
  128.             break;
  129.         }
  130.     }
  131. }
  132.  
  133.  
  134. /*
  135.  * Change the background pattern of the frontmost window.
  136.  * Ignore if the front window is a DA window.
  137.  */
  138. static pascal void
  139. DoColorMenu (short item)
  140. {
  141. WindowPtr    w;
  142.  
  143.     w = FrontWindow ();
  144.     if (((WindowPeek) w)->windowKind < 0) return;    /* front is DA window */
  145.     switch (item)
  146.     {
  147.         case cWhite:    BackPat ((ConstPatternParam) &qd.white); break;
  148.         case cLtGray:    BackPat ((ConstPatternParam) &qd.ltGray); break;
  149.         case cGray:        BackPat ((ConstPatternParam) &qd.gray); break;
  150.         case cDkGray:    BackPat ((ConstPatternParam) &qd.dkGray); break;
  151.         case cBlack:    BackPat ((ConstPatternParam) &qd.black); break;
  152.     }
  153.     SetWRefCon (w, item);        /* save item number for menu checkmarking */
  154.     EraseRect (&w->portRect);
  155. }
  156.  
  157.  
  158. static pascal void
  159. DoMClobber (MenuHandle m)
  160. {
  161.     DisposeMenu (m);
  162. }
  163.  
  164.  
  165. static void
  166. SetItemEnableState (MenuHandle m, short item, Boolean state)
  167. {
  168.     if (state)
  169.         EnableItem (m, item);
  170.     else
  171.         DisableItem (m, item);
  172. }
  173.  
  174.  
  175. /*
  176.  * Adjust menus when mouse click occurs in menu bar.
  177.  * File menu:
  178.  * - New is enabled if window count hasn't exceeded limit.
  179.  * - Close is enabled if there is a window visible.
  180.  * Color menu:
  181.  * - Check item corresponding to color of frontmost window.
  182.  * Window menu:
  183.  * - Check item corresponding to frontmost window.
  184.  */
  185.  
  186. static pascal void
  187. AdjustMenus (void)
  188. {
  189. short    nItems, i;
  190. Str255    iTitle, wTitle;
  191. short    mark;
  192.  
  193.     SetItemEnableState(fileMenu, newWind, windCount < maxWind);
  194.     SetItemEnableState(fileMenu, closeWind, FrontWindow() != (WindowPtr) nil);
  195.     if (windCount > 0)
  196.     {
  197.         for (i = cWhite; i <= cBlack; i++)
  198.         {
  199.             mark = (GetWRefCon (FrontWindow ()) == i ? checkMark : noMark);
  200.             SetItemMark (colorMenu, i, mark);
  201.         }
  202.         GetWTitle (FrontWindow(), wTitle);
  203.         nItems = CountMItems (windowMenu);
  204.         for (i = 1; i <= nItems; i++)
  205.         {
  206.             GetMenuItemText (windowMenu, i, iTitle);
  207.             mark = (EqualString (iTitle, wTitle, false, true) ? checkMark : noMark);
  208.             SetItemMark (windowMenu, i, mark);
  209.         }
  210.     }
  211. }
  212.  
  213.  
  214. /* --------------- */
  215. /* Window handling */
  216. /* --------------- */
  217.  
  218.  
  219. static pascal void
  220. DoWUpdate (Boolean resized)
  221. {
  222. WindowPtr    w;
  223.  
  224.     GetPort (&w);
  225.     EraseRect (&w->portRect);    /* repaint w/background pattern */
  226. }
  227.  
  228.  
  229. /*
  230.  * Mouse was clicked in close box.  Remove the window handler (which
  231.  * causes the window to be disposed of), and delete the window title
  232.  * from the Window menu.  If the window was the last one, delete the
  233.  * Window and Color menus entirely.
  234.  *
  235.  * Skel makes sure the port is pointing to the appropriate window, so
  236.  * this procedure can determine which window had its close box clicked,
  237.  * without being told explicitly.
  238.  */
  239.  
  240. static pascal void
  241. DoWClose (void)
  242. {
  243. WindowPtr    w;
  244.  
  245.     GetPort (&w);            /* window to be closed */
  246.     SkelRmveWind (w);
  247. }
  248.  
  249.  
  250. /*
  251.  * Dispose of window.  Skel makes sure the port is pointing to the
  252.  * appropriate window, so this procedure can determine which window
  253.  * is to be disposed, of without being told explicitly.
  254.  *
  255.  * Also delete the window title from the Window menu.  If the window
  256.  * was the last one, delete the Window and Color menus entirely.
  257.  */
  258.  
  259. static pascal void
  260. DoWClobber (void)
  261. {
  262. WindowPtr    w;
  263. short        i, mItems;
  264. Str255        iTitle, wTitle;
  265.  
  266.     GetPort (&w);            /* window to be closed */
  267.     GetWTitle (w, wTitle);
  268.     DisposeWindow (w);
  269.     if (--windCount == 0)
  270.     {
  271.         SkelRmveMenu (windowMenu);    /* last window - clobber menus */
  272.         SkelRmveMenu (colorMenu);
  273.     }
  274.     else
  275.     {
  276.         for (i = 1, mItems = CountMItems (windowMenu); i <= mItems; ++i)
  277.         {
  278.             GetMenuItemText (windowMenu, i, iTitle);
  279.             if (EqualString (iTitle, wTitle, false, true))
  280.             {
  281.                 DeleteMenuItem (windowMenu, i);
  282.                 break;
  283.             }
  284.         }
  285.     }
  286. }
  287.  
  288.  
  289. /*
  290.  * Make new window.  Locate at (100, 100) if no other windows, else
  291.  * offset slightly from front window.  The window title is the next
  292.  * window number (1, 2, 3, ...).  If this is the first window, create
  293.  * the Window and Color menus.  Add the window title as the last item
  294.  * of the Window menu.
  295.  *
  296.  * If the maximum window count is reached, disable New in the
  297.  * File menu.
  298.  */
  299.  
  300. static void
  301. MakeWindow (void)
  302. {
  303. WindowPtr    w;
  304. Rect        r;
  305. Str255        s;
  306.  
  307.     if ((w = FrontWindow ()) == (WindowPtr) nil)
  308.         SetRect (&r, 100, 100, 300, 250);
  309.     else
  310.     {
  311.         SkelGetWindContentRect (w, &r);
  312.         OffsetRect (&r, 20, 20);
  313.         if (r.left > 480 || r.top > 300)    /* keep on screen */
  314.             OffsetRect (&r, 40 - r.left, 40 - r.top);
  315.     }
  316.     NumToString (++windNum, s);
  317.     if (SkelQuery (skelQHasColorQD))
  318.         w = NewCWindow (nil, &r, s, true, noGrowDocProc, (WindowPtr) -1L, true, 0L);
  319.     else
  320.         w = NewWindow (nil, &r, s, true, noGrowDocProc, (WindowPtr) -1L, true, 0L);
  321.     (void) SkelWindow (w,
  322.                 nil,        /* mouseclicks */
  323.                 nil,        /* key clicks */
  324.                 DoWUpdate,    /* updates */
  325.                 nil,        /* activate/deactivate events */
  326.                 DoWClose,    /* close window, remove from menu */
  327.                 DoWClobber,    /* dispose of window */
  328.                 nil,        /* idle proc */
  329.                 false);        /* irrelevant, since no idle proc */
  330.  
  331.     if (windCount++ == 0)    /* if first window, create new menus */
  332.     {
  333.         colorMenu = NewMenu (cMenuNum, "\pColor");
  334.         AppendMenu (colorMenu, "\pWhite;Light Gray;Gray;Dark Gray;Black");
  335.         (void) SkelMenu (colorMenu, DoColorMenu, DoMClobber, false, false);
  336.         windowMenu = NewMenu (wMenuNum, "\pWindow");
  337.         (void) SkelMenu (windowMenu, DoWindowMenu, DoMClobber, false, true);
  338.     }
  339.     AppendMenu (windowMenu, s);
  340.     SetWRefCon (w, cWhite);
  341. }
  342.  
  343.  
  344. static void
  345. SetupMenus (void)
  346. {
  347.     SkelApple (nil, nil);                        /* initialize Apple menu */
  348.     fileMenu = NewMenu (fMenuNum, "\pFile");    /* make File menu handler */
  349.     AppendMenu (fileMenu, "\pNew/N;Close/W;(-;Quit/Q");
  350.     (void) SkelMenu (fileMenu, DoFileMenu, DoMClobber, false, true);
  351.     SkelSetMenuHook (AdjustMenus);
  352. }
  353.  
  354.  
  355. /* ------------ */
  356. /* Main program */
  357. /* ------------ */
  358.  
  359. int
  360. main (void)
  361. {
  362.     SkelInit ((SkelInitParamsPtr) nil);            /* initialize */
  363.     SetupMenus ();
  364.     SkelEventLoop ();                            /* loop 'til Quit selected */
  365.     SkelCleanup ();                                /* clean up */
  366. }
  367.